//    Copyright (C) 2013  <lugocreation@gmail.com>
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
package org.jpgolay.me.batch;

import java.awt.event.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import javax.swing.*;
import org.jpgolay.me.agency.Agency;
import org.jpgolay.me.item.Item;
import org.jpgolay.me.number.NextNumber;
import org.jpgolay.me.order.OrderRow;
import org.jpgolay.me.persistence.ObjectCRUD;
import org.jpgolay.me.stock.log.LogStock;
import org.jpgolay.me.supplier.Supplier;
import org.jpgolay.me.util.MEDate;
import org.jpgolay.me.util.Parameter;

// Referenced classes of package org.jpgolay.me.batch:
//            BatchPanel, BatchCmdPanel, Batch, BatchPrint
public class BatchController {

    private class MouseClickBuyId extends MouseAdapter {

        public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() == 2) {
                actionBuyIdField();
            }
        }

        MouseClickBuyId() {
        }
    }

    private class MouseClickItemBatch extends MouseAdapter {

        public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() == 2) {
                actionItemBatchField();
            }
        }

        MouseClickItemBatch() {
        }
    }

    public BatchController(BatchPanel batchPanel, BatchCmdPanel batchCmdPanel, Parameter param) {
        checkCmd = false;
        modify = false;
        write = false;
        this.batchPanel = batchPanel;
        this.batchCmdPanel = batchCmdPanel;
        this.param = param;
        desktop = param.getDesktop();
        crud = new ObjectCRUD();
        changes = new PropertyChangeSupport(this);
        initLaw();
        initBatchPanel();
        initBatchCmdPanel();
    }

    private void initLaw() {
        if (param.getAccessLaw().length() >= 27 && param.getAccessLaw().charAt(27) == '1') {
            write = true;
        }
    }

    private void initBatchPanel() {
        batchPanel.cleanField(true);
        batchPanel.getBuyIdJTextField().addMouseListener(new MouseClickBuyId());
        batchPanel.getItemBatchJTextField().addMouseListener(new MouseClickItemBatch());
        batchPanel.getInputStockQuantityJTextField().addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                if (batchPanel.getInputStockQuantity() == null || batchPanel.getInputStockQuantity().equals("")) {
                    batchCmdPanel.getSaveBatch().setEnabled(false);
                    batchCmdPanel.getPrintBatch().setEnabled(false);
                } else {
                    batchCmdPanel.getSaveBatch().setEnabled(write);
                    batchCmdPanel.getPrintBatch().setEnabled(true);
                }
            }
        });
    }

    private void initBatchCmdPanel() {
        batchCmdPanel.getSaveBatch().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (modify) {
                    actionModify();
                } else {
                    actionSave();
                }
            }
        });
        batchCmdPanel.getDelete().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (modify) {
                    actionDelete();
                }
            }
        });
        batchCmdPanel.getClear().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                batchPanel.cleanField(true);
                batchCmdPanel.getSaveBatch().setEnabled(false);
                batchCmdPanel.getDelete().setEnabled(false);
                batchCmdPanel.getPrintBatch().setEnabled(false);
                checkCmd = false;
                modify = false;
            }
        });
        batchCmdPanel.getPrintBatch().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionPrintLabels();
            }
        });
        batchCmdPanel.getSaveBatch().setEnabled(false);
        batchCmdPanel.getDelete().setEnabled(false);
        batchCmdPanel.getPrintBatch().setEnabled(false);
    }

    private void actionSave() {
        if (verifyRequirements()) {
            Integer id = (Integer) crud.create(31, null);
            if (id != null) {
                batch = (Batch) crud.read(id, 31);
                batch.setAgencyId(new Integer(batchPanel.getAgencyId()));
                if (batchPanel.getBatchPrice() != null) {
                    batch.setBatchPrice(new BigDecimal(batchPanel.getBatchPrice()));
                }
                batch.setBoxGTIN(batchPanel.getBoxGTIN());
                batch.setBuyId(batchPanel.getBuyId());
                if (batchPanel.getDLC() != null) {
                    batch.setDateDLC(batchPanel.getDLC());
                }
                if (batchPanel.getDLUO() != null) {
                    batch.setDateDLUO(batchPanel.getDLUO());
                }
                if (batchPanel.getInputStockDate() != null) {
                    batch.setInputStockDate(batchPanel.getInputStockDate());
                }
                batch.setDeliveryForm(batchPanel.getDeliveryForm());
                batch.setDeltaInventory(new BigDecimal("0.00"));
                batch.setInputStockQuantity(new BigDecimal(batchPanel.getInputStockQuantity()));
                if (batchPanel.getItemBatch() != null) {
                    batch.setItemBatch(batchPanel.getItemBatch());
                }
                batch.setItemGTIN(batchPanel.getItemGTIN());
                batch.setItemId(batchPanel.getItemId());
                batch.setNotes(batchPanel.getNotes());
                batch.setPackaging(new BigDecimal(batchPanel.getPackaging()));
                batch.setPalletGTIN(batchPanel.getPalletGTIN());
                batch.setSscc(batchPanel.getSSCC());
                batch.setStatus(new Integer(batchPanel.getStatus()));
                batch.setStockQuantity(new BigDecimal(batchPanel.getInputStockQuantity()));
                batch.setSupplierGLN(batchPanel.getSupplierGLN());
                batch.setSupplierId(batchPanel.getSupplierID());
                batch.setTruckingCompagny(batchPanel.getTruckingCompany());
                batch.setUnit(batchPanel.getUnit());
                batch.setUserId(param.getUserId());
                if (crud.update(batch, 31)) {
                    id = (Integer) crud.create(32, null);
                    if (id != null) {
                        LogStock logStock = (LogStock) crud.read(id, 32);
                        logStock.setBatchId(batch.getId());
                        logStock.setDate((new MEDate()).getPlain());
                        logStock.setOperation("ENTREE");
                        logStock.setDe(batch.getSupplierId());
                        logStock.setVers("Agence " + batch.getAgencyId().toString());
                        logStock.setItemId(batch.getItemId());
                        logStock.setNotes("R\351ception (n\260 lot " + batch.getItemBatch() + ")");
                        logStock.setQuantity(batch.getInputStockQuantity());
                        logStock.setUserId(param.getUserId());
                        crud.update(logStock, 32);
                    }
                }
                if (checkCmd) {
                    OrderRow or = new OrderRow();
                    or.setArticleId(orderRow.getArticleId());
                    or.setDesignation(orderRow.getDesignation());
                    or.setFactureId(orderRow.getFactureId());
                    or.setId(orderRow.getId());
                    or.setLine(orderRow.getLine());
                    or.setPrixUnitaire(orderRow.getPrixUnitaire());
                    or.setPrixVente(orderRow.getPrixVente());
                    or.setQuantite(batch.getInputStockQuantity());
                    or.setReliquatId(orderRow.getReliquatId());
                    or.setRemise(orderRow.getRemise());
                    or.setStatus(batch.getInputStockQuantity());
                    or.setTotalHt(orderRow.getTotalHt());
                    or.setTvaId(orderRow.getTvaId());
                    or.setUpdateLastTime(orderRow.getUpdateLastTime());
                    or.setUserId(orderRow.getUserId());
                    or.setVenteId(orderRow.getVenteId());
                    or.setBatchId(batch.getId());
                    or.setLotId(batch.getItemBatch());
                    listOrderRow = new ArrayList();
                    listOrderRow.add(or);
                    changes.firePropertyChange("checkCmd", "old", "checkCmd");
                }
                batchPanel.cleanField(false);
                batchCmdPanel.getSaveBatch().setEnabled(false);
                batchCmdPanel.getPrintBatch().setEnabled(false);
                checkCmd = false;
            }
        }
    }

    private void actionPrintLabels() {
        String result = JOptionPane.showInputDialog(null, "Combien d'\351tiquettes souhaitez vous imprimer ?", "1");
        BigInteger quantity = null;
        try {
            quantity = new BigInteger(result);
        } catch (NumberFormatException e) {
            quantity = new BigInteger("1");
        }
        Item item = (Item) crud.read(batch.getItemId(), 11);
        if (item != null) {
            BatchPrint print = null;
            for (int i = 0; i < quantity.intValue(); i++) {
                print = new BatchPrint(item, batch, false, param);
                print = null;
            }

        }
    }

    private boolean verifyRequirements() {
        if (batchPanel.getItemId() == null) {
            JOptionPane.showMessageDialog(null, "R\351f\351rence de l'article invalide !");
            return false;
        }
        if (batchPanel.getInputStockQuantity() == null) {
            JOptionPane.showMessageDialog(null, "Quantit\351 invalide !");
            return false;
        }
        try {
            new BigDecimal(batchPanel.getInputStockQuantity());
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(null, "Quantit\351 invalide ! \n(valeur num\351rique uniquement)");
            return false;
        }
        try {
            if (batchPanel.getBatchPrice() != null) {
                new BigDecimal(batchPanel.getBatchPrice());
            }
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(null, "Prix du lot invalide ! \n(valeur num\351rique uniquement)");
            batchPanel.setBatchPrice("0.00");
            return false;
        }
        try {
            if (batchPanel.getItemBatch() != null) {
                new Integer(batchPanel.getItemBatch());
            }
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(null, "N\260 de lot invalide ! \n(valeur num\351rique (entier) uniquement)");
            return false;
        }
        return true;
    }

    private void actionBuyIdField() {
        changes.firePropertyChange("buyIdField", "old", "buyIdField");
    }

    private void actionItemBatchField() {
        if (nextNumber == null) {
            nextNumber = new NextNumber();
        }
        if (batchCmdPanel.getSaveBatch().isEnabled()) {
            batchPanel.setItemBatch(nextNumber.getBatchNumber());
        }
    }

    private void actionOrderRowSetPanel() {
        batchPanel.setItemId(orderRow.getArticleId());
        batchPanel.setInputStockQuantity(orderRow.getQuantite().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
        batchPanel.setBatchPrice(orderRow.getTotalHt().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
        if (orderRow.getQuantite().compareTo(new BigDecimal("0.00")) == 1) {
            checkCmd = true;
            batchCmdPanel.getSaveBatch().setEnabled(true);
            batchCmdPanel.getPrintBatch().setEnabled(true);
        }
    }

    private void actionSupplierSetPanel() {
        batchPanel.setSupplierID(supplier.getId());
        batchPanel.setSupplierGLN(supplier.getGln());
    }

    private void actionAgencySetPanel() {
        batchPanel.setAgencyId(agency.getId().intValue());
    }

    private void actionRead(Integer id) {
        modify = true;
        batch = (Batch) crud.read(id, 31);
        if (batch != null) {
            actionLoad();
        }
    }

    private void actionLoad() {
        batchPanel.setAgencyId(batch.getAgencyId().intValue());
        batchPanel.setBatchPrice(batch.getBatchPrice().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
        batchPanel.setBoxGTIN(batch.getBoxGTIN());
        batchPanel.setBuyId(batch.getBuyId());
        batchPanel.setDLC(batch.getDateDLC());
        batchPanel.setDLUO(batch.getDateDLUO());
        batchPanel.setInputStockDate(batch.getInputStockDate());
        batchPanel.setDeliveryForm(batch.getDeliveryForm());
        batchPanel.setInputStockQuantity(batch.getInputStockQuantity().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
        batchPanel.setItemBatch(batch.getItemBatch());
        batchPanel.setItemGTIN(batch.getItemGTIN());
        batchPanel.setItemId(batch.getItemId());
        batchPanel.setNotes(batch.getNotes());
        batchPanel.setPackaging(batch.getPackaging().setScale(0).toString());
        batchPanel.setPalletGTIN(batch.getPalletGTIN());
        batchPanel.setSSCC(batch.getSscc());
        batchPanel.setStatus(batch.getStatus().intValue());
        batchPanel.setStockQuantity(batch.getStockQuantity().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
        batchPanel.setDeltaInventory(batch.getStockQuantity().subtract(batch.getDeltaInventory()).setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
        batchPanel.setInventoryDate(batch.getInventoryDate());
        batchPanel.setSupplierGLN(batch.getSupplierGLN());
        batchPanel.setSupplierID(batch.getSupplierId());
        batchPanel.setTruckingCompany(batch.getTruckingCompagny());
        batchPanel.setUnit(batch.getUnit());
        batchPanel.setLastUpdateUser(batch.getUserId());
        batchPanel.setLastUpdateTime(batch.getUpdateLastTime());
        batchPanel.setId(batch.getId().toString());
        batchCmdPanel.getSaveBatch().setEnabled(write);
        batchCmdPanel.getDelete().setEnabled(write);
        batchCmdPanel.getPrintBatch().setEnabled(true);
    }

    private void actionDelete() {
        int reponse = JOptionPane.showConfirmDialog(null, "Etes-vous certain de vouloir suprimer ce lot ?", "Confirmation", 1, 2, null);
        switch (reponse) {
            case 0: // '\0'
                if (crud.delete(batch.getId(), batch.getUpdateLastTime(), 31)) {
                    Integer id = (Integer) crud.create(32, null);
                    if (id != null) {
                        LogStock logStock = (LogStock) crud.read(id, 32);
                        logStock.setBatchId(batch.getId());
                        logStock.setDate((new MEDate()).getPlain());
                        logStock.setOperation("SORTIE");
                        logStock.setDe(batch.getSupplierId());
                        logStock.setVers("Agence " + batch.getAgencyId().toString());
                        logStock.setItemId(batch.getItemId());
                        logStock.setNotes("LOT SUPRIMER (n\260 lot " + batch.getItemBatch() + ")");
                        logStock.setQuantity(batch.getInputStockQuantity());
                        logStock.setUserId(param.getUserId());
                        crud.update(logStock, 32);
                    }
                }
                batchPanel.cleanField(true);
                batchCmdPanel.getSaveBatch().setEnabled(false);
                batchCmdPanel.getDelete().setEnabled(false);
                batchCmdPanel.getPrintBatch().setEnabled(false);
                modify = false;
            // fall through

            case -1:
            case 1: // '\001'
            case 2: // '\002'
            default:
                return;
        }
    }

    private void actionModify() {
        if (verifyRequirements()) {
            batch.setAgencyId(new Integer(batchPanel.getAgencyId()));
            if (batchPanel.getBatchPrice() != null) {
                batch.setBatchPrice(new BigDecimal(batchPanel.getBatchPrice()));
            }
            batch.setBoxGTIN(batchPanel.getBoxGTIN());
            batch.setBuyId(batchPanel.getBuyId());
            if (batchPanel.getDLC() != null) {
                batch.setDateDLC(batchPanel.getDLC());
            }
            if (batchPanel.getDLUO() != null) {
                batch.setDateDLUO(batchPanel.getDLUO());
            }
            if (batchPanel.getInputStockDate() != null) {
                batch.setInputStockDate(batchPanel.getInputStockDate());
            }
            batch.setDeliveryForm(batchPanel.getDeliveryForm());
            batch.setInputStockQuantity(new BigDecimal(batchPanel.getInputStockQuantity()));
            if (batchPanel.getItemBatch() != null) {
                batch.setItemBatch(batchPanel.getItemBatch());
            }
            batch.setItemGTIN(batchPanel.getItemGTIN());
            batch.setItemId(batchPanel.getItemId());
            batch.setNotes(batchPanel.getNotes());
            batch.setPackaging(new BigDecimal(batchPanel.getPackaging()));
            batch.setPalletGTIN(batchPanel.getPalletGTIN());
            batch.setSscc(batchPanel.getSSCC());
            batch.setStatus(new Integer(batchPanel.getStatus()));
            batch.setStockQuantity(new BigDecimal(batchPanel.getInputStockQuantity()));
            batch.setSupplierGLN(batchPanel.getSupplierGLN());
            batch.setSupplierId(batchPanel.getSupplierID());
            batch.setTruckingCompagny(batchPanel.getTruckingCompany());
            batch.setUnit(batchPanel.getUnit());
            batch.setUserId(param.getUserId());
            if (crud.update(batch, 31)) {
                Integer id = (Integer) crud.create(32, null);
                if (id != null) {
                    LogStock logStock = (LogStock) crud.read(id, 32);
                    logStock.setBatchId(batch.getId());
                    logStock.setDate((new MEDate()).getPlain());
                    logStock.setOperation("MODIFICATION (n\260 lot " + batch.getItemBatch() + ")");
                    logStock.setDe(batch.getSupplierId());
                    logStock.setVers("Agence " + batch.getAgencyId().toString());
                    logStock.setItemId(batch.getItemId());
                    logStock.setNotes("D\351tails V\351rifier l'historique du lot !");
                    logStock.setQuantity(batch.getInputStockQuantity());
                    logStock.setUserId(param.getUserId());
                    crud.update(logStock, 32);
                }
            }
            batchPanel.cleanField(true);
            batchCmdPanel.getSaveBatch().setEnabled(false);
            batchCmdPanel.getDelete().setEnabled(false);
            batchCmdPanel.getPrintBatch().setEnabled(false);
            modify = false;
        }
    }

    public void addPropertyChangeListener(PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }

    public void removePropertyChangeListener(PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }

    public void setPieceId(String pieceId) {
        this.pieceId = pieceId;
        batchPanel.setBuyId(pieceId);
    }

    public String getPieceId() {
        return pieceId;
    }

    public ArrayList getListOrderRow() {
        return listOrderRow;
    }

    public OrderRow getOrderRow() {
        return orderRow;
    }

    public void setOrderRow(OrderRow orderRow) {
        this.orderRow = orderRow;
        actionOrderRowSetPanel();
    }

    public Supplier getSupplier() {
        return supplier;
    }

    public void setSupplier(Supplier supplier) {
        this.supplier = supplier;
        actionSupplierSetPanel();
    }

    public Agency getAgency() {
        return agency;
    }

    public void setAgency(Agency agency) {
        this.agency = agency;
        actionAgencySetPanel();
    }

    public void modifyBatch(String batchId) {
        actionRead(new Integer(batchId));
    }
    private BatchPanel batchPanel;
    private BatchCmdPanel batchCmdPanel;
    private Parameter param;
    private JDesktopPane desktop;
    private ObjectCRUD crud;
    private boolean checkOrder;
    private PropertyChangeSupport changes;
    private OrderRow orderRow;
    private Supplier supplier;
    private Agency agency;
    private boolean checkCmd;
    private String pieceId;
    private NextNumber nextNumber;
    private ArrayList listOrderRow;
    private boolean modify;
    private Batch batch;
    private boolean write;
}
